iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0

在之前的好幾篇文章,談論主鍵 (prirmary key)、條件限制 (constraints)、索引 (index),我都主張 Datomic 是一種高階資料庫,提供了高階的語意,讓使用者不用想太多,因為很多『重要的決定』,Datomic 都幫你做了。

  • 不用想要設計主鍵,因為已經設計好了
  • 基本條件限制只思考「不重複值」即可,其它的要嘛就是 Datomic 幫你決定了、要嘛就是 Datomic 不推荐你做,再來就是商業邏輯相關的。
  • 索引只要考慮 AVET 即可,其它三種都不用想。

然而,『效能改進』恰好就是與高階對立: 高階語意是你用 API 就好,不用管底層的細節;效能改進卻往往是需要對底層的運作細節有點了解才能做的。

由於我本人並沒有在 Datomic 的公司工作,沒有機會一賭所有的 Datomic 底層運作細節,這邊只能基於我對 Datomic 底層運作的有限了解提出兩種在實際工作中用過的效能改進作法。

直接存取 Datomic 的索引

考慮如下的兩筆資料,其中,:person/roles 這個屬性它的 :db/cardinalitymany ,所以它可以一對多。

  [{:db/id "temp-1"
    :person/name "John"
    :person/roles [:driver :student]}
   {:db/id "temp-2"
    :person/name "Mary"
    :person/roles [:driver :teacher]}]

如果我們已經有了第一筆資料的資料實體編碼 (entity id),想要查出,這個資料實體對應的 person/roles 是哪幾個時,可以怎麼做呢?

最直覺的作法是用查詢做。

(d/q '[:find ?r
       :in $ ?e
       :where [?e :person/roles ?r]]
      (db/db) entity-id)

然而,它的效能普通,如果我們改成用『索引直接存取』,可以更快。

;;; Compare the speed of `d/datoms` and ordinary `d/q` query
(time (map :v
           (d/datoms (db/db) :eavt
                     entity-id
                     attr-id)))

;; => 
;; (out) "Elapsed time: 0.091166 msecs"
;; (:driver :student)

(time (d/q '[:find ?r
             :in $ ?e
             :where [?e :person/roles ?r]]
           (db/db) entity-id))

;; =>
;; (out) "Elapsed time: 2.878042 msecs"
;; #{[:student] [:driver]}

當然,上述的比較是簡單地用 Clojure 的 time 函數做一個極度簡單地比較。我多做了幾次實驗,如果是 d/q 這個函數的話,它的內部可能有很多最佳化的可能性,每次執行的結果還會不太一樣,從 2 msec 到 8 msec 都有。另一方面,datoms 的執行時間則穩定得多。

總結來講,d/datoms 是相對低階許多的存取方式,並不好寫,但是可以在某些關鍵時刻讓 Datomic 發揮極高的效能。

遇到 OLAP 查詢,做變更擷取 (change data capture)

Datomic 的查詢非常地彈性而且有許多不同的用法,有人曾經實驗過,把 Datomic 當圖形資料庫來使用,發現查詢效能遠勝過 SQL 資料庫。

然而,它在 OLAP 的使用情境,查詢的效能還比 Postgres 差了 10 倍到 20 倍。(這個數字來自我的體感數字,沒有精確的量測。) 可惜,在 OLAP 的世界,Postgres 也都還不是最快的資料庫,要跟 DuckDB 比的話,都還遠遠比不上。

那…如果我們要改進的查詢效能,很不巧的就是 OLAP 的分析查詢,該怎麼辦?這種恰好是 Datomic 的弱項的事情,只好做變更擷取,直接把 Datomic 的內容,同步到 SQL 資料庫了。plenish 就是這樣子的一個函式庫,它可以幫你把 Datomic 的資料內容即時同步到 Postgres 。

參考資料

  1. stackoverflow 上的 Datomic Raw Index Access 範例
  2. Using Datomic as a Graph Database

其它資源

  1. 歡迎訂閱 PruningSuccess 電子報,主要談論軟體開發、資料處理、資料分析等議題。
  2. 歡迎加入 Clojure 社群

上一篇
效能改進 -- part 1
下一篇
Datomic 的商業價值:新的資料庫典範
系列文
Datomic,內建事件溯源的資料庫。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言